package com.dongbing.support;

import com.dongbing.enums.BatchTaskBizType;
import com.dongbing.support.executor.BatchTaskExecutor;
import com.dongbing.support.loader.BatchTaskDataLoader;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanCreationException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.stereotype.Component;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 收集 BatchTaskExecutor、BatchTaskDataLoader
 */
@Component
public class CollectBeanPostProcessor implements BeanPostProcessor {

    private static final Map<BatchTaskBizType, BatchTaskExecutor<?>> EXECUTOR_MAP = new ConcurrentHashMap<>();

    private static final Map<BatchTaskBizType, BatchTaskDataLoader<?, ?>> LOADER_MAP = new ConcurrentHashMap<>();

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {

        if (bean instanceof BatchTaskExecutor) {
            BatchTaskBizType batchTaskBizType = ((BatchTaskExecutor<?>) bean).type();
            if (EXECUTOR_MAP.containsKey(batchTaskBizType)) {
                throw new BeanCreationException("存在重复批量任务类型 EXECUTOR_TYPE = " + batchTaskBizType);
            } else {
                EXECUTOR_MAP.put(batchTaskBizType, ((BatchTaskExecutor<?>) bean));
            }
        }

        if (bean instanceof BatchTaskDataLoader) {
            BatchTaskBizType batchTaskBizType = ((BatchTaskDataLoader<?, ?>) bean).type();
            if (LOADER_MAP.containsKey(batchTaskBizType)) {
                throw new BeanCreationException("存在重复批量任务类型 LOADER_TYPE = " + batchTaskBizType);
            } else {
                LOADER_MAP.put(batchTaskBizType, ((BatchTaskDataLoader<?, ?>) bean));
            }
        }

        return BeanPostProcessor.super.postProcessAfterInitialization(bean, beanName);
    }

    @SuppressWarnings("all")
    public static BatchTaskExecutor getExecutor(BatchTaskBizType batchTaskBizType) {
        return EXECUTOR_MAP.get(batchTaskBizType);
    }

    @SuppressWarnings("all")
    public static BatchTaskDataLoader getLoader(BatchTaskBizType batchTaskBizType) {
        return LOADER_MAP.get(batchTaskBizType);
    }
}
